package cn.rulian.base.auth.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.rulian.base.auth.bo.Organ;
import cn.rulian.base.auth.service.OrganService;
import cn.rulian.base.auth.vo.OrganVo;
import cn.rulian.base.common.dto.Message;
import cn.rulian.base.common.vo.Result;
import cn.rulian.base.common.vo.TreeVo;

/**
 * 机构管理 Controller
 */

@Controller
@RequestMapping("/base/auth/organ")
public class OrganController {
	
	@Autowired
	private OrganService service;
	
	private final String path="base/auth/organ_"; //页面基本路径

	/**
	 * 页面基本路径
	 */
	private String getPath()
	{
		return path;
	}
	
	/**
	 * 列表页面
	 */
	@RequestMapping("/listPage")
	public String listPage() {
		return this.getPath()+"list";
	}

	/**
	 * 查询
	 */
	@RequestMapping("/listData")
	@ResponseBody
	public Result listData(OrganVo vo) {
		return service.query(vo);
	}
	
	/**
	 * 查询所有数据
	 */
	@RequestMapping("/findAll")
	@ResponseBody
	public Result findAll() {
		Sort sort = new Sort(Direction.ASC, "code"); // 排序
		List<Organ> list = service.findAll(sort);
		for(Organ bo:list)
		{
			if(bo.getFather() != null)
			{
				bo.set_parentId(bo.getFather().getId());
			}
		}
		Result result = new Result();
		result.setRows(list);
		return result;
	}
	

	/**
	 * 查询所有数据,供下拉列表使用。
	 */
	@RequestMapping("/findAllForselect")
	@ResponseBody
	public List<TreeVo> findAllForselect() {
		
		//查询数据
		Sort sort = new Sort(Direction.ASC, "code"); // 排序
		List<Organ> boList = service.findAll(sort);
		
		//列表转换
		List<TreeVo> dtoList = new ArrayList<>();
		for(Organ bo:boList)
		{
			TreeVo dto = new TreeVo();
			dto.setId(bo.getId());
			dto.setText(bo.getName());
			if(bo.getFather() != null)
			{
				dto.set_parentId(bo.getFather().getId());
			}
			dtoList.add(dto);
		}
		
		//构造子结构
		for(TreeVo dto:dtoList)
		{
			for(TreeVo son:dtoList)
			{
				if(son.get_parentId() != null && son.get_parentId().longValue() == dto.getId().longValue())
				{ 
					List<TreeVo> children = dto.getChildren();
					if(children==null)
					{
						children = new ArrayList<>();
					}
					children.add(son);
					dto.setChildren(children);
				}
			}
		}
		
		//只保留顶层元素
		List<TreeVo> showList = new ArrayList<>();
		for(TreeVo dto:dtoList)
		{
			if(dto.get_parentId() == null)
			{
				showList.add(dto);
			}
		}
		
		return showList;
	}

	/**
	 * 增加页面
	 */
	@RequestMapping("/addPage")
	public String addPage(Model model, Long fatherId) {

		if(fatherId != null)
		{
			model.addAttribute("father", service.findOne(fatherId));
		}
		
		return this.getPath()+"add";
	}

	/**
	 * 增加
	 */
	@RequestMapping("/add")
	@ResponseBody
	public Message add(OrganVo vo,Long fatherId) {
		Message rm = new Message();
		Organ bo = vo.getObj();
		bo.setCode(bo.getInnerCode());
		bo.setAddTime(new Date());
		
		//配置父机构
		if(fatherId != -1)
		{
			Organ father = service.findOne(fatherId);
			if(father != null)
			{
				bo.setFather(father);
				bo.setCode(father.getCode() + bo.getInnerCode());
			}
		}
		
		Organ other = service.getDao().findByCode(bo.getCode());
		if(other != null)
		{
			rm.setMsg("编码重复，请修改！");
			rm.setCode(Message._ERROR);
			return rm;
		}
		
		try {
			service.save(bo);
			
			rm.setMsg("保存成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("保存失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}

	/**
	 * 修改页面
	 */
	@RequestMapping("/updatePage")
	public String updatePage(Model model, Long id) {
		model.addAttribute("bo", service.findOne(id));
		return this.getPath()+"update";
	}

	/**
	 * 修改
	 */
	@RequestMapping("/update")
	@ResponseBody
	public Message update(OrganVo vo,Long id) {
		Message rm = new Message();
		try {
			Organ obj = vo.getObj();
			Organ bo = service.findOne(id);
			
			
			if(!bo.getInnerCode().equals(obj.getInnerCode()))
			{//编码修改
				String code = obj.getInnerCode();
				if(bo.getFather() != null)
				{
					code = bo.getFather().getCode() + code;
				}
				
				//编码验重
				Organ other = service.getDao().findByCode(code);
				if(other != null)
				{
					rm.setMsg("编码重复，请修改！");
					rm.setCode(Message._ERROR);
					return rm;
				}
				
				bo.setCode(code);
				bo.setInnerCode(obj.getInnerCode());
			}
			
			bo.setLocked(obj.getLocked());
			bo.setName(obj.getName());
			bo.setMark(obj.getMark());
			
			service.save(bo);
			this.updateSonCode(bo.getId());
			
			rm.setMsg("保存成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("保存失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}
	
	/**
	 * 更新子机构的编码
	 */
	private void updateSonCode(Long fatherId)
	{
		List<Organ> list = service.getDao().findByFather_id(fatherId);
		for(Organ organ: list)
		{
			organ.setCode(organ.getFather().getCode() + organ.getInnerCode());
			service.save(organ);
			this.updateSonCode(organ.getId());
		}
	}

	/**
	 * 删除
	 */
	@RequestMapping("/delete")
	@ResponseBody
	public Message delete(Long ids[]) {
		Message rm = new Message();
		try {
			for(Long id:ids)
			{
				service.delete(id);
			}
			
			rm.setMsg("删除成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("删除失败！！！可能原因：<br/>1、机构下存在用户。 <br/>2、有下级机构。");
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}
	
	/**
	 * 详情页面
	 */
	@RequestMapping("/detailPage")
	public String detailPage(Model model, Long id) {
		model.addAttribute("bo", service.findOne(id));
		return this.getPath()+"detail";
	}

	
}
